package com.samp.base.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

/**
 * 此类主要实现文件夹的删除，复制，移动。<br>
 *     参考：https://blog.csdn.net/zhufenghao/article/details/51089854
 */
public class FileUtilsDemo {



    /**
     * 删除指定文件夹或文件。
     * @param file
     * @return
     */
    public static boolean delete(File file){
        if( file == null || !file.exists() ){
            return false;
        }
        if( file.isFile() ){
            file.delete();
        }else {
            for( File subFiles : file.listFiles() ){
                delete(subFiles);
            }
            file.delete();
        }
        return true;
    }

    /**
     * 复制文件或文件夹。
     * @param src 源文件或文件夹
     * @param destDir 目标文件或文件夹，没有会创建。
     * @return
     */
    public static boolean copy( File src, File destDir){
        if( src == null || !src.exists() ){
            return false;
        }
        if( !destDir.exists() ){
            destDir.mkdir();
        }
        if( src.isFile() ){
            copyFile(src, destDir);
        }else {
            File newSrcDir = new File(destDir,src.getName());
            if( !newSrcDir.exists() ){
                newSrcDir.mkdir();
            }
            for (File subFile : src.listFiles()) {
                copy(subFile,newSrcDir);
            }
        }
        return true;
    }

    public static boolean move(File src, File dstDir) {
        if ( !src.exists() ) {
            return false;
        }
        if ( !dstDir.exists() ) {
            dstDir.mkdirs();
        }
        if (src.isFile()) {// 文件
            moveFile(src, dstDir);
        } else {// 文件夹
            String oldSrcName = src.getName();
            int srcNumber = 0;
            File newSrcDir = new File(dstDir, oldSrcName);
            while (newSrcDir.exists()) {
                srcNumber++;
                String newSrcName = oldSrcName + "-copy" + srcNumber;
                newSrcDir = new File(dstDir, newSrcName);
            }
            newSrcDir.mkdirs();
            for (File srcSub : src.listFiles()) {
                move(srcSub, newSrcDir);// 递归移动源文件夹下子文件和文件夹
            }
            src.delete();
        }
        return true;
    }

    /**
     * 将指定文件拷贝至指定目录,如果文件存在，则新的文件重命名为fileName-copy.txt.
     * @param srcFile 必须是文件。
     * @param destDir 目标路径不存在则创建。
     * @return
     */
    private static boolean copyFile(File srcFile, File destDir){
        if( srcFile == null || destDir == null ){
            return false;
        }
        if( !srcFile.exists() || srcFile.isDirectory() ){
            return false;
        }
        if( !destDir.exists() ){
            destDir.mkdir();
        }
        File newFile = new File(destDir, srcFile.getName());
        if( newFile.exists() ){
            String[] fileNames = getFileNameAndSuffix(srcFile.getName());
            String newFileName = fileNames[0] + "-copy" + fileNames[1];
            newFile = new File(destDir, newFileName);
        }
        try {
            FileChannel fileIn = new FileInputStream(srcFile).getChannel();
            FileChannel fileOut = new FileOutputStream(newFile).getChannel();
            fileIn.transferTo(0, fileIn.size(), fileOut);
            fileIn.close();
            fileOut.close();
        } catch (IOException e) {
            return false;
        }
        return true;
    }

    private static boolean moveFile( File srcFile, File destDir ){
        if( srcFile == null || destDir == null ){
            return false;
        }
        if( !srcFile.exists() || srcFile.isDirectory() ){
            return false;
        }
        if( !destDir.exists() ){
            destDir.mkdir();
        }
        File dstFile = new File(destDir, srcFile.getName());
        if (srcFile.renameTo(dstFile)) {// 直接重命名绝对路径速度更快
            return true;
        } else {// 文件已经存在，需要自动编号复制再删除源文件
            copyFile(srcFile, destDir);
            srcFile.delete();
        }
        return true;
    }

    /**
     * 返回文件的文件名和后缀。
     * @param fileName
     * @return
     */
    private static String[] getFileNameAndSuffix( String fileName ){
        String nameBody;
        String suffix;
        int dotPos = fileName.lastIndexOf(".");
        if( dotPos > 0 ){
            nameBody = fileName.substring(0, dotPos);
            suffix = fileName.substring(dotPos);
        }else {
            nameBody = fileName;
            suffix = "";
        }
        return new String[]{nameBody,suffix};
    }

    public static void main(String[] args) {
        String path = "D:\\temp\\classes-delete";
        //delete(new File(path));
//        String fileName = "solr";
//        String[] strs = getFileNameAndSuffix(fileName);
//        if( strs != null && strs.length > 0 ){
//            for (String str : strs  ) {
//                System.out.println(str);
//            }
//        }
//        copyFile(new File("D:\\temp\\bbb"),new File(path));
//        boolean flag = copy(new File("D:\\temp\\classes"),new File(path));
//        System.out.println(flag);
//        moveFile(new File("D:\\temp\\bbb.12"),new File(path));
        move(new File("D:\\temp\\classes"),new File(path));
    }
}
